package com.financialDog.javaTool.config;


import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.financialDog.javaTool.reportModel.ConfigVo;
import com.financialDog.javaTool.reportModel.FileVo;
import com.xwintop.xcore.util.javafx.TooltipUtil;
import javafx.collections.ObservableList;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;

import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Consumer;

@Slf4j
public class ConfigManager {

    public static final String LOCAL_CONFIG_PATH = "./config_list.json";

    public static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;

    public final static ConfigManager INSTANCE = new ConfigManager(LOCAL_CONFIG_PATH);

    public static ConfigManager getInstance() {
        return INSTANCE;
    }

    private final String localConfigPath;

    private List<ConfigVo> configVoList;

    private ConfigVo currentConfig;

    public ConfigManager(String localConfigPath) {
        this.localConfigPath = localConfigPath;

        if (StringUtils.isNotEmpty(localConfigPath)) {
            localConfigPath();
        }
    }

    public ConfigVo getCurrentConfig(){
        return currentConfig;
    }

    public void localConfigPath() {
        configVoList = new ArrayList<>();
        try {
            Path path = Paths.get(this.localConfigPath);
            if (!Files.exists(path)) {
                return;
            }
            String json = new String(Files.readAllBytes(path), DEFAULT_CHARSET);
            JSON.parseArray(json, ConfigVo.class).forEach(config -> {
                this.addOrUpdatePlugin(config, exist -> {
                    exist.setUpdateDate(config.getUpdateDate());
                    exist.setCreateDate(config.getCreateDate());
                    exist.setProjectName(config.getProjectName());
                    exist.setFileList(config.getFileList());
                });
            });
            if (configVoList.size() != 0){
                currentConfig = configVoList.get(0);
            }
        } catch (IOException e) {
            log.error("读取文件失败", e);
        }
    }

    private void addOrUpdatePlugin(ConfigVo configVo,  Consumer<ConfigVo> ifExists) {
        ConfigVo exists = getConfig(configVo.getProjectName());
        if (exists == null) {
            this.configVoList.add(configVo);
        } else {
            ifExists.accept(exists);
        }
    }

    public void saveToFile() throws IOException {
        String json = JSON.toJSONString(this.configVoList, true);
        Files.write(
                Paths.get(this.LOCAL_CONFIG_PATH),
                json.getBytes(DEFAULT_CHARSET)
        );
    }


    public boolean checkNameForProject(String projectName){
        ConfigVo configVo = configVoList.stream().filter(e->e.getProjectName().equals(projectName)).findFirst().orElse(null);
        if (configVo == null){
            return true;
        }else{
            return false;
        }
    }

    public ConfigVo getConfig(String projectName) {
        return this.configVoList.stream()
                .filter(configVo -> Objects.equals(configVo.getProjectName(), projectName))
                .findFirst().orElse(null);
    }

    public void addNewProject(String projectName){
        if (StringUtils.isEmpty(projectName)){
            TooltipUtil.showToast("项目名称不能为空");
            return;
        }
        ConfigVo configVo = new ConfigVo();
        configVo.setProjectName(projectName);
        configVo.setCreateDate(DateUtil.format(new Date(), "YYYY-MM-DD hh:mm"));
        configVo.setUpdateDate(DateUtil.format(new Date(), "YYYY-MM-DD hh:mm"));
        currentConfig = configVo;
        configVoList.add(configVo);
        return;
    }

    public void generateConfigTableData(ObservableList<Map<String, String>> tableData){
        configVoList.forEach(configVo->{
            HashMap<String, String> hashMap = new HashMap<String, String>();
            hashMap.put("name", configVo.getProjectName());
            hashMap.put("createTime", configVo.getCreateDate());
            hashMap.put("updateTime",  configVo.getUpdateDate());
            tableData.add(hashMap);
        });
    }

    public void generateFileTableData(ObservableList<Map<String, String>> tableData){
        if (currentConfig != null && currentConfig.getFileList() != null){
            currentConfig.getFileList().forEach(fileVo -> {
                HashMap<String, String> hashMap = new HashMap<String, String>();
                hashMap.put("name", fileVo.getFileName());
                hashMap.put("yearType", fileVo.getYear());
                hashMap.put("time",  fileVo.getTime());
                hashMap.put("type",  fileVo.getType());
                hashMap.put("filePath", fileVo.getFilePath());
                tableData.add(hashMap);
            });
        }
    }
}
